import {combineReducers} from "redux";

import {pathOr, union} from 'ramda'
import {CHANNELS_ACTIONS, TOPICS_ACTIONS} from "../../constants/ActionTypes";

export const initPagination = {
  isFetching: false,
  nextPageUrl: undefined,
  totals: 0,//总数
  totalPages: 0,
  nextPageNumber: 1,//下一页
  hasMore: true,
  addCount: 0, //添加了几条数据
  ids: [],
  number: 1,//当前页
  aggregations: {},//聚类数据
  suggest: {},//建议器
  //lastTime: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'),
}

// Creates a reducer managing pagination, given the action types to handle,
// and a function telling how to extract the key from an action.
const paginate = ({types, mapActionToKey}) => {

  if (typeof mapActionToKey !== 'function') {
    throw new Error('Expected mapActionToKey to be a function.')
  }

  const {REQUEST, SUCCESS, FAILURE, ADD} = types

  const updatePagination = (state = initPagination, action) => {
    switch (action.type) {
      case REQUEST:
        return {
          ...state,
          isFetching: true
        }
      case SUCCESS:
        const meta = pathOr(initPagination, ['response', 'meta'], action)
        return {
          ...state,
          isFetching: false,
          ids: action.singlePage ? action.response.result : union(state.ids, action.response.result),
          nextPageUrl: action.response.nextPageUrl,
          hasMore: !meta.last,
          totals: meta.totalElements,
          totalPages: meta.totalPages,
          pageCount: meta.number + 1,//下一页
          number: meta.number,//当前页
          //addCount: meta.numberOfElements,//当前页的数量,暂时在分页结果注释掉吧,SUCCESS中暂时未用到,在ADD的时候有用到
          aggregations: {
            ...state.aggregations,
            ...meta.aggregations,
          },//聚类数据，不一定有
          suggest: meta.suggest,//建议数据
        }
      case ADD://特殊需求,如：发表新评论、定时加载新的订阅数据
        const arr = Array.isArray(action.response.result) ? action.response.result : new Array(1).fill(action.response.result)
        return {
          ...state,
          totals: state.totals + arr.length,
          ids: union(arr, state.ids),
          addCount: arr.length,
          //lastTime: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'),
          isFetching: false,
        }
      case FAILURE:
        return {
          ...state,
          isFetching: false,
          hasMore: false,
        }
      default:
        return state
    }
  }

  return (state = {}, action) => {
    // Update pagination by key
    switch (action.type) {
      case REQUEST:
      case SUCCESS:
      case FAILURE:
      case ADD :
        const key = mapActionToKey(action)
        return {
          ...state,
          [key]: updatePagination(state[key], action)
        }
      default:
        return state
    }
  }
}


export default combineReducers({
  topicsByType: paginate({
    mapActionToKey: action => action.topicsType,
    types: TOPICS_ACTIONS
  }),
  channelsByType: paginate({
    mapActionToKey: action => action.channelsType,
    types: CHANNELS_ACTIONS
  }),
})
